package dispute;

import jade.core.AID;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import agents.util.AgentUtil;

import ontology.actions.general.ReturnCompleteInfo;
import ontology.actions.vo.VOReturnKnowledge;
import ontology.concepts.vo.VOCase;
import ontology.concepts.vo.VOOutcome;
import ontology.models.contract.Violation;
import ontology.models.negotiation.Part;
import ontology.models.negotiation.Proposal;

public class NegotiationRoom {
	
	private AID announcer;
	private String roomDoor; //The identifier of the negotiation room
	private String description; //a little description of the issue handled in this negotiation
	private List<Round> rounds; //a set o rounds taken during the negotiation
	private int round; //the actual round
	private int caseIndex;
	
	//Members
	private Panel negotiators; //The other members of the VO
	private VOCase violation;//The reason to the conflict
	private List<Proposal> proposals; //Proposals on the table from the UMCourt and from the parties
	private NEGOTIATION_STATUS status; //The status of the negotiation;
	
	public NegotiationRoom(){
		rounds = new ArrayList<Round>();
		round = -1;
		caseIndex = -1;
		negotiators = new Panel();
		status = NEGOTIATION_STATUS.PENDING;
		proposals = new ArrayList<Proposal>();
	}
	
	public NegotiationRoom(Violation violation, String roomDoor){
		this.roomDoor = roomDoor;
		rounds = new ArrayList<Round>();
		round = -1;
		caseIndex = -1;
		negotiators = new Panel();
		this.violation = cloneToVOCase(violation);
		status = NEGOTIATION_STATUS.PENDING;
		proposals = new ArrayList<Proposal>();
	}
	
	private VOCase cloneToVOCase(Violation violation2) {
		VOCase newCase = new VOCase();
		newCase.setNorm(violation2.getNorm());
		newCase.setParties(new ArrayList<String>(violation2.getAffectedParts()));
		newCase.setViolation(AgentUtil.cloneObligation(violation2.getViolation()));
		return newCase;
	}
	
	public AID getAnnouncer() {
		return announcer;
	}

	public void setAnnouncer(AID announcer) {
		this.announcer = announcer;
	}

	private void incRound(){
		round++;
	}
	
	public String getRoomDoor() {
		return roomDoor;
	}

	public void setRoomDoor(String roomDoor) {
		this.roomDoor = roomDoor;
	}

	public int round(){
		return round;
	}
	
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public Round getRound(int index) {
		return rounds.get(index);
	}
	public void addRound(Round round) {
		incRound();
		round.setRound(this.round);
		rounds.add(round);
	}
	public Panel getNegotiators() {
		return negotiators;
	}
	public void setNegotiators(Panel negotiators) {
		this.negotiators = negotiators;
	}
	public VOCase getViolation() {
		return violation;
	}
	public void setViolation(VOCase violation) {
		this.violation = violation;
	}

	public void addPart(Part p) {
		negotiators.getPanel().put(p.getAid(), p);
	}

	public List<Proposal> getProposals() {
		return proposals;
	}

	public void setProposals(List<Proposal> proposals) {
		this.proposals = proposals;
	}
	
	public List<Round> getRounds() {
		return rounds;
	}

	public void setRounds(List<Round> rounds) {
		this.rounds = rounds;
	}

	public Proposal getCurrentProposal(){
		if(caseIndex != -1){
			return proposals.get(caseIndex);
		}
		else return null;
	}
	
	public Proposal getNextProposal(){
		caseIndex++;
		if(caseIndex < proposals.size())
			return proposals.get(caseIndex);
		else return null;
	}
	
	public NEGOTIATION_STATUS getStatus() {
		return status;
	}

	public void setStatus(NEGOTIATION_STATUS status) {
		this.status = status;
	}

	public String toShortString() {
		return "NegotiationRoom [roomDoor=" + roomDoor + ", round=" + round
				+ "]";
	}

	public static enum NEGOTIATION_STATUS{
		PENDING,
		ONGOING,
		CLOSED_SUCCESSFUL,
		CLOSED_UNSUCCESSFUL
	}

	public void fillProposals(AID agent, ReturnCompleteInfo rk) {
		jade.util.leap.ArrayList similarities = rk.getSimilarities();
		jade.util.leap.ArrayList outcomes = rk.getOutcomes();
		jade.util.leap.ArrayList utilities = rk.getUtilities();
				
		ArrayList<Integer> order = new ArrayList<Integer>();
		while (!similarities.isEmpty())
		{
			Double max = Double.MIN_VALUE;
			int maxIndex = 0;
			
			for (int i=0;i<similarities.size();i++)
			{
				if ((Double)similarities.get(i) > max)
				{
					max = (Double)similarities.get(i);
					maxIndex = i;
				}
			}
			
			order.add(maxIndex);
			similarities.remove(maxIndex);
		}
		for (int i=0; i<order.size();i++)
		{
			int index = (Integer) order.get(i);
			Proposal proposal = new Proposal();
			proposal.setOutcome((VOOutcome) outcomes.get(index));
			proposal.setUtility((Double) utilities.get(index));
			proposal.setDate(new Date());
			proposal.setIsAnsProposal(false);
			proposal.setIsNewProposal(true);
			proposal.setProponent(agent);
			proposals.add(proposal);
		}
		caseIndex = -1;
	}

	public Round getCurrentRound() {
		return rounds.get(round);		
	}
	
}
